package com.wingsfrog.ZcVideo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import com.Player.Core.PlayerClient;
import com.Player.Core.PlayerSearchCore;
import com.Player.Core.ComCustomClient;
import com.Player.Source.*;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.String;
import java.util.ArrayList;
import java.util.List;

public class ZcVideo extends CordovaPlugin {
    private ComCustomClient comCustomClient;
    private CallbackContext callbackContext;
    private PlayerClient playerclient;
    private static List<PlayNode> nodeList = new ArrayList<PlayNode>();

    public static TVideoFile file;
    private final static String address = "app.umeye.cn";
    private final static Integer port = 8300;
    private final static String username = "nologinuser";
    private final static String password = "nologinuser";

    private final static String customName = "umeyehome_custom";
    private final static String sDevVendorFlag = "def";
    public static String nodelistXmlname = "//data//data//com.wingsfrog.genius_rc//NodelistXml.xml";

    private String getImsi() {

        Context con = this.cordova.getActivity().getApplicationContext();
        TelephonyManager mTelephonyMgr = (TelephonyManager) con
                .getSystemService(Context.TELEPHONY_SERVICE);
        String secureId = android.provider.Settings.Secure.getString(
                con.getContentResolver(),
                android.provider.Settings.Secure.ANDROID_ID);
        String subscriberId = mTelephonyMgr.getSubscriberId();
        String deviceId = mTelephonyMgr.getDeviceId();

        return secureId;
    }

    private static TLoginParam initLogin() {
        TLoginParam tmpLoginParam = new TLoginParam();
        tmpLoginParam.iClientType = 3;
        tmpLoginParam.sDevModel = "Android";
        tmpLoginParam.sDevVersion = "v1.0.1";
        tmpLoginParam.sClientOwner = customName;
        tmpLoginParam.sClientCustomFlag = customName;
        tmpLoginParam.sClientLanguage = "SimpChinese";
        return tmpLoginParam;
    }

    // TODO 将这几个helper函数移到一个单独的文件中
    public static List<PlayNode> GetAllChildren() {
        List<PlayNode> list = new ArrayList<PlayNode>();
        for (int i = 0; i < nodeList.size(); i++) {
            if (!nodeList.get(i).IsDirectory() && !nodeList.get(i).IsDvr()) {
                list.add(nodeList.get(i));
//				Log.i("nodeName", "NodeList.get(i):"
//						+ NodeList.get(i).getName());
            }
        }
        // AllChildrenList = list;
        return list;
    }
    public int AddUmeyeCloud(PlayerClient playerclient,
                                    boolean isCamera, TFileListNode addNodeParent, String nodeName,
                                    String devId, int channels, String username, String password,
                                    int stream) {
        int ret = -1;
        if (playerclient.IsLogin()) {
            if (isCamera)
                ret = playerclient.UMEye_AddP2pCloudCamera(addNodeParent,
                        nodeName, devId, username, password, channels - 1,
                        stream);

            else
                ret = playerclient.UMEye_AddP2pCloudDev(addNodeParent,
                        nodeName, devId, username, password, channels, stream);
        } else {
            if (playerclient.LoginEx() > 0)
                if (isCamera)
                    ret = playerclient.UMEye_AddP2pCloudCamera(addNodeParent,
                            nodeName, devId, username, password, channels - 1,
                            stream);

                else
                    ret = playerclient.UMEye_AddP2pCloudDev(addNodeParent,
                            nodeName, devId, username, password, channels,
                            stream);
            else
                ret = -1;
        }
        return ret;
    }
    /**
     * 找到节点ID的父节点
     *
     * @param id
     *            节点ID
     * @return 如果找不到，则返回null,否则返回相应父节点
     */
    public static PlayNode GetParent(int id, List<PlayNode> NodeList) {
        int parent = -100;
        int i;
        for (i = 0; i < NodeList.size(); i++) {
            if (NodeList.get(i).node.dwNodeId == id) {
                parent = NodeList.get(i).node.dwParentNodeId;
                break;
            }
        }
        if (i == NodeList.size()) {
            return null;
        }
        for (int k = 0; k < NodeList.size(); k++) {
            if (NodeList.get(k).node.dwNodeId == parent) {
                return NodeList.get(k);
            }
        }
        return null;
    }
    /**
     * 得到每一个节点的层数
     */
    public static void GetLevel(List<PlayNode> NodeList) {
        for (int k = 0; k < NodeList.size(); k++) {
            PlayNode node = NodeList.get(k);
            String[] temp = node.getRoute().split("//");
            node.setLevel(temp.length - 1);
        }
        // System.out.println("OK");
    }
    /**
     * 获取每一个节点的路径route,例如"测试-风采楼"
     */
    private static void GetChildrenRoute(List<PlayNode> NodeList) {
        for (int k = 0; k < NodeList.size(); k++) {
            PlayNode node = NodeList.get(k);
            PlayNode parent = GetParent(node.node.dwNodeId, NodeList);
            if (parent == null) {
                node.setRoute(node.node.sNodeName);
            } else {
                node.setRoute(parent.getRoute() + "//"
                        + node.node.sNodeName);
            }
        }
    }
    private static void GetChildCountAndLanLon(List<PlayNode> NodeList) {
        // boolean hasLanLon;
        for (int i = 0; i < NodeList.size(); i++) {
            // hasLanLon = false;// 默认没有经纬度
            if (NodeList.get(i).getName().contains("组织"))
                System.out.println("找到");
            if (NodeList.get(i).IsDirectory()) {
                int total = 0;
                for (int k = 0; k < NodeList.size(); k++) {
                    if (NodeList.get(k).node.dwParentNodeId == NodeList.get(i).node.dwNodeId)// 表示是其子节点
                    {
                        total++;
                        // if (NodeList.get(k).HasLatLon()) {
                        // hasLanLon = true;
                        // }
                    }
                }
                NodeList.get(i).setChildrenCount(total);
            }

            // if (NodeList.get(i).IsDirectory()) {
            // NodeList.get(i).setChildrenHasLatLon(hasLanLon);
            // }
        }

    }
    private boolean GetDevList(PlayerClient playerclient, int dwQueryNodeId, List<PlayNode> NodeList) {
        int hDevList = playerclient.DevListQuery(dwQueryNodeId);

        if (hDevList != 0) {
            playerclient.DevListMoveFirst(hDevList);// 移动到子节点中的第一个节点

            while (true) {

                TFileListNode tmpFileListNode = playerclient
                        .DevListGetNextNode(hDevList);// 移动到兄弟结点

                if (tmpFileListNode != null) // 为空时退出
                {
                    if (dwQueryNodeId == 0) {
                        tmpFileListNode.dwParentNodeId = 0;
                    }

                    if (tmpFileListNode.iNodeType == NodeType.DIRECTORY
                            || tmpFileListNode.iNodeType == NodeType.DVR) {
                        // continue;
                        System.out.println("目录名:" + tmpFileListNode.sNodeName
                                + "  ID号" + tmpFileListNode.dwNodeId);

                        PlayNode node = new PlayNode(tmpFileListNode);
                        NodeList.add(node);

                        GetDevList(playerclient, tmpFileListNode.dwNodeId,
                                NodeList); // 循环，移动到兄弟节点
                    } else {
                        if (tmpFileListNode.iNodeType == NodeType.CAMERA) {
                            System.out.println("摄像头名:"
                                    + tmpFileListNode.sNodeName
                                    + " 设备ID:"
                                    + tmpFileListNode.sDevId
                                    + " 连接类型:"
                                    + tmpFileListNode.iConnMode
                                    + "  ID号:"
                                    + tmpFileListNode.dwNodeId
                                    + "   父节点ID号"
                                    + tmpFileListNode.dwParentNodeId
                                    + ",在线状态 ："
                                    + (tmpFileListNode.ucDevState == 1 ? "在线"
                                    : "离线"));
//							System.out.println("是否支持PTZ:"
//									+ tmpFileListNode.ucIfPtz + "是否支持经度纬度:"
//									+ tmpFileListNode.ucIfLongLat + " 经度:"
//									+ tmpFileListNode.dwLongitude + " 纬度:"
//									+ tmpFileListNode.dwLatitude);

                            for (int i = 0; i < tmpFileListNode.iDevPopNum; i++) {
                                System.out.println("权限表:"
                                        + tmpFileListNode.ucDevPopTable[i]);
                            }
                            PlayNode node = new PlayNode(tmpFileListNode);
                            NodeList.add(node);
                        } else {
                            System.out.println("其他类型的节点");
                        }

                    }

                } else {
                    break;
                }
            }
        }
        playerclient.DevListRelease(hDevList);
        return NodeList.size() > 0;
    }
    private boolean GetDataFromServer(PlayerClient playerclient) {
        boolean HaveData = false;
        if (playerclient != null) {
            List<PlayNode> tempNodeList = new ArrayList<PlayNode>();
            HaveData = GetDevList(playerclient, 0, tempNodeList); // 获取设备列表
            GetChildCountAndLanLon(tempNodeList);
            // CommonData.InitLonLat(NodeList);
            GetChildrenRoute(tempNodeList);
            GetLevel(tempNodeList);

            if (tempNodeList.size() == 0) {
                if (ZcVideo.nodeList.size() == 1) {
                    ZcVideo.nodeList = tempNodeList;
                }
            } else {
                ZcVideo.nodeList = tempNodeList;
            }
        }

        return HaveData;
    }
    @Override
    protected void pluginInitialize() {
        super.pluginInitialize();
        this.playerclient = new PlayerClient();

        // TODO 登录及获取节点列表
        TLoginParam tmpLoginParam = this.initLogin();
        String imsi = this.getImsi();
        playerclient.CLTSetNetState(1); // TODO 有网络时初始化为1,无网络时初始化为0
        playerclient.InitParam(address, port, "", "", imsi, tmpLoginParam);
        playerclient.CLTStartClient(address, port);
        playerclient.InitParam(address, port, username, password, imsi, tmpLoginParam);
        playerclient.SetSaveMode(1);
        playerclient.SetVendorClientFlag(sDevVendorFlag, customName);
        playerclient.SetSaveDirName(nodelistXmlname);

        int result = playerclient.LoginEx(); // 执行登录操作
        if (result > 0) GetDataFromServer(playerclient);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.playerclient.CLTStopClient();
        this.playerclient.RealseClient();
    }

    private void connect(JSONArray data, CallbackContext callbackContext) {
        try {
            String umid = args.getString(0);
            String username = args.getString(1);
            String password = args.getString(2);
            JSONArray data = args.getJSONArray(3);
            int resCode =  comCustomClient.ComConnect(umid,username,password,1,1,1,1,1,1);
            byte[] bytes = new byte[data.length()];
            for(int i = 0; i < data.length(); ++i) {
                bytes[i] = (byte) data.getInt(i);
            }
            comCustomClient.ComSendData(bytes)
        } catch (JSONException e) {
            e.printStackTrace();
            callbackContext.error("发送的json数据格式错误");
        }
        callbackContext.success();
    }

    @Override
    public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;



        if ("search".equals(action)) { // 搜索摄像头
            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    doSearch(args, callbackContext);
                }
            });
        }else if("connect".equals(action)){
            if(comCustomClient == null){
                comCustomClient = new ComCustomClient();
            }
            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    connect(args, callbackContext);
                }
            });
        } else if ("showVideoView".equals(action)) { // 播放
            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    try {
                        showVideoView(args, callbackContext);
                    } catch (JSONException e) {
                        e.printStackTrace();
                        callbackContext.error(e.getMessage());
                    }
                }
            });
        } else if ("searchVideo".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    searchVideo(args, callbackContext);
                }
            });
        } else if ("playVideo".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    playVideo(args, callbackContext);
                }
            });
        } else if ("changePwd".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    changePwd(args, callbackContext);
                }
            });
        } else
            return false;
        return true;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        //支付页面返回处理
        //        if (requestCode == REQUEST_CODE_PAYMENT) {
        if (resultCode == Activity.RESULT_OK) {
            String result = data.getExtras().getString("pay_result");
            /* 处理返回值
             * "success" - payment succeed
             * "fail"    - payment failed
             * "cancel"  - user canceld
             * "invalid" - payment plugin not installed
             */
            String errorMsg = data.getExtras().getString("error_msg"); // 错误信息
            String extraMsg = data.getExtras().getString("extra_msg"); // 错误信息
            if ("success".equals(result)) {
                this.callbackContext.success(result);
            } else if ("fail".equals(result)) {
                this.callbackContext.error(result + ":" + errorMsg);
            } else if ("cancel".equals(result)) {
                this.callbackContext.error(result + ":" + errorMsg);
            } else if ("invalid".equals(result)) {
                this.callbackContext.error(result + ":" + errorMsg);
            }
        } else if (resultCode == Activity.RESULT_CANCELED) {
            this.callbackContext.error(requestCode);
        }
    }

    public void doSearch(JSONArray args, CallbackContext context) {
        JSONArray array = new JSONArray();
        int searchRet = playerclient.StartSearchDev(10);// 10代表等待多少秒
        for (int i = 0; i < searchRet; i++) {
            TSearchDev tsearch = playerclient.SearchDevByIndex(i);
            JSONObject object = new JSONObject();
            try {
                object.put("vendorId", tsearch.dwVendorId);
                object.put("sDevModel", tsearch.sDevModel);
                object.put("sUMDevModel", tsearch.sUMDevModel);
                object.put("deviceName", tsearch.sDevName);
                object.put("deviceUmid", tsearch.sDevId);
                object.put("deviceUserID", tsearch.sDevUserName);
                object.put("devicePassword", "");
                object.put("bIfSetPwd", tsearch.bIfSetPwd);
                object.put("sCloudServerAddr", tsearch.sCloudServerAddr);
                object.put("usCloudServerPort", tsearch.usCloudServerPort);
                object.put("deviceChannel", tsearch.usChNum);
                object.put("iDevIdType", tsearch.iDevIdType);
                object.put("bIfAllowSetIpaddr", tsearch.bIfAllowSetIpaddr);
                object.put("bIfEnableDhcp", tsearch.bIfEnableDhcp);
                object.put("iMsgVerNo", tsearch.iMsgVerNo);
                object.put("sDevIpaddr", tsearch.sDevIpaddr);
                object.put("iDevPort", tsearch.iDevPort);
                object.put("iDevNtsUdpPort", tsearch.iDevNtsUdpPort);
                object.put("iEmpowerMode", tsearch.iEmpowerMode);
                object.put("sEmpowerCode", tsearch.sEmpowerCode);
                object.put("iAdapterNum", tsearch.iAdapterNum);
                object.put("sAdapterName_1", tsearch.sAdapterName_1);
                object.put("sAdapterMac_1", tsearch.sAdapterMac_1);
                object.put("sIpaddr_1", tsearch.sIpaddr_1);
                object.put("sNetmask_1", tsearch.sNetmask_1);
                object.put("sGateway_1", tsearch.sGateway_1);
                object.put("sAdapterName_2", tsearch.sAdapterName_2);
                object.put("sAdapterMac_2", tsearch.sAdapterMac_2);
                object.put("sIpaddr_2", tsearch.sIpaddr_2);
                object.put("sNetmask_2", tsearch.sNetmask_2);
                object.put("sGateway_2", tsearch.sGateway_2);
                object.put("sAdapterName_3", tsearch.sAdapterName_3);
                object.put("sAdapterMac_3", tsearch.sAdapterMac_3);
                object.put("sIpaddr_3", tsearch.sIpaddr_3);
                object.put("sNetmask_3", tsearch.sNetmask_3);
                object.put("sGateway_3", tsearch.sGateway_3);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            array.put(object);
        }
        playerclient.StopSearchDev();
        context.success(array);
    }

    public void showVideoView(JSONArray args, CallbackContext context) throws JSONException {
        String umid = args.getString(0);
        String username = args.getString(1);
        String password = args.getString(2);
        Integer channelNo = args.getInt(3);
        for (PlayNode playNode : ZcVideo.nodeList) {
            playerclient.DelDevNode(playNode.getNode());
        }
        ZcVideo.nodeList.clear();
        // TODO 测试下面这个+1能否工作
        this.AddUmeyeCloud(playerclient, false, null, "Device", umid, channelNo + 1, username, password, 1);

        GetDataFromServer(playerclient);
        Intent intent = new Intent(cordova.getActivity().getApplicationContext(), ZcVideoActivity.class);
        //cordova本身实现的调起别的activity的方法，并将调用返回的结果传给插件
        this.cordova.startActivityForResult(this, intent, 1);
        //cordova.getActivity().startActivityForResult(intent,1);//这个方法不能返回结果给插件
    }

    private Date_Time parseTime(JSONObject time) throws JSONException {
        Date_Time sTime = new Date_Time();
        sTime.year = (short) time.getInt("year");
        sTime.month = (short) time.getInt("month");
        sTime.day = (byte) time.getInt("day");
        sTime.hour = (byte) time.getInt("hour");
        sTime.minute = (byte) time.getInt("minute");
        sTime.second = (byte) time.getInt("second");
        return sTime;
    }

    private JSONObject TVideoFileToJson(TVideoFile v1) throws JSONException {
        JSONObject obj = new JSONObject();
        obj.put("channel", v1.Channel);
        obj.put("eday", v1.eday);
        obj.put("ehour", v1.ehour);
        obj.put("eminute", v1.eminute);
        obj.put("emonth", v1.emonth);
        obj.put("esecond", v1.esecond);
        obj.put("eyear", v1.eyear);
        obj.put("fileName", v1.FileName);
        obj.put("nFileSize", v1.nFileSize);
        obj.put("nFileType", v1.nFileType);
        obj.put("nParam1", v1.nParam1);
        obj.put("nParam2", v1.nParam2);
        obj.put("sday", v1.sday);
        obj.put("shour", v1.shour);
        obj.put("sminute", v1.sminute);
        obj.put("smonth", v1.smonth);
        obj.put("ssecond", v1.ssecond);
        obj.put("syear", v1.syear);
        return obj;
    }

    private TVideoFile JsonToTVideoFile(JSONObject obj) throws JSONException {
        TVideoFile file = new TVideoFile();
        file.Channel = (short) obj.getInt("channel");
        file.eday = (byte) obj.getInt("eday");
        file.ehour = (byte) obj.getInt("ehour");
        file.eminute = (byte) obj.getInt("eminute");
        file.emonth = (byte) obj.getInt("emonth");
        file.esecond = (byte) obj.getInt("esecond");
        file.eyear = (short) obj.getInt("eyear");
        file.FileName = obj.getString("fileName");
        file.nFileSize = obj.getInt("nFileSize");
        file.nFileType = (short) obj.getInt("nFileType");
        file.nParam1 = obj.getInt("nParam1");
        file.nParam2 = obj.getInt("nParam2");
        file.sday = (byte) obj.getInt("sday");
        file.shour = (byte) obj.getInt("shour");
        file.sminute = (byte) obj.getInt("sminute");
        file.smonth = (short) obj.getInt("smonth");
        file.ssecond = (byte) obj.getInt("ssecond");
        file.syear = (short) obj.getInt("syear");
        return file;
    }

    private int GetLen(TVideoFile t) {
        int day = (t.eday - t.sday) * 24 * 3600;
        int hour = (t.ehour - t.shour) * 3600;
        int minute = (t.eminute - t.sminute) * 60;
        int second = (t.esecond - t.ssecond);
        return day + hour + minute + second;
    }

    public void searchVideo(JSONArray args, CallbackContext context) {
        String umid, username, password, deviceId;
        Date_Time sTime, eTime;
        Integer channelNo, recordType;
        try {
            umid = args.getString(0);
            username = args.getString(1);
            password = args.getString(2);
            channelNo = args.getInt(3);
            if (password.equals("null")) password = ""; // FIXME 修复这个转换
            JSONObject startTime = args.getJSONObject(4);
            JSONObject endTime = args.getJSONObject(5);
            sTime = parseTime(startTime);
            eTime = parseTime(endTime);
            recordType = args.getInt(6);
        } catch (JSONException e) {
            e.printStackTrace();
            context.error("JSON参数不合法");
            return;
        }

        for (PlayNode playNode : ZcVideo.nodeList) {
            playerclient.DelDevNode(playNode.getNode());
        }
        ZcVideo.nodeList.clear();
        this.AddUmeyeCloud(playerclient, false, null, "Device", umid, channelNo + 1, username, password, 1);

        GetDataFromServer(playerclient);
        try {
            JSONArray result = new JSONArray();
            PlayerSearchCore searchCore = new PlayerSearchCore(cordova.getActivity());
            PlayNode playNode = ZcVideo.nodeList.get(channelNo + 1);
            deviceId = playNode.getDeviceId();
            int ret = searchCore.SearchRecFileEx(deviceId, sTime, eTime, recordType);// 18100000返回1或-1
            if (ret > 0) {
                while (true) {
                    TVideoFile videoFile = searchCore.GetNextRecFile(); // 获取录像文件
                    if (videoFile == null) { // 查找结点结束
                        break;
                    } else
                        result.put(TVideoFileToJson(videoFile));
                }
                searchCore.Release();
                context.success(result);
            } else {
                context.error("搜索失败");
            }
        } catch (JSONException e) {
            context.error("解析搜索结果时出现问题");
        }
    }

    public void playVideo(JSONArray args, CallbackContext context) {
        String umid, username, password, deviceId;
        Integer channelNo;
        try {
            umid = args.getString(0);
            username = args.getString(1);
            password = args.getString(2);
            channelNo = args.getInt(3);
            if (password.equals("null")) password = "";

            for (PlayNode playNode : ZcVideo.nodeList) {
                playerclient.DelDevNode(playNode.getNode());
            }
            ZcVideo.nodeList.clear();
            this.AddUmeyeCloud(playerclient, false, null, "Device", umid, channelNo + 1, username, password, 1);
            GetDataFromServer(playerclient);

            Intent intent = new Intent(cordova.getActivity().getApplicationContext(), AcVod.class);
            PlayNode playNode = ZcVideo.nodeList.get(channelNo + 1);
            deviceId = playNode.getDeviceId();

            intent.putExtra("deviceId", deviceId);
            ZcVideo.file = JsonToTVideoFile(args.getJSONObject(4));
            this.cordova.startActivityForResult(this, intent, 1);
        } catch (JSONException e) {
            e.printStackTrace();
            context.error(e.getMessage());
        }
    }

    public void changePwd(JSONArray args, CallbackContext context) {
        String umid, username, password, newPassword, deviceId;
        Integer channelNo;
        try {
            umid = args.getString(0);
            username = args.getString(1);
            password = args.getString(2);
            newPassword = args.getString(3);
            channelNo = args.getInt(4);
            if (password.equals("null")) password = ""; // FIXME 修复这个转换
        } catch (JSONException e) {
            e.printStackTrace();
            context.error("JSON参数不合法");
            return;
        }
        for (PlayNode playNode : ZcVideo.nodeList) {
            playerclient.DelDevNode(playNode.getNode());
        }
        ZcVideo.nodeList.clear();
        this.AddUmeyeCloud(playerclient, false, null, "Device", umid, channelNo + 1, username, password, 1);
        GetDataFromServer(playerclient);
        PlayerSearchCore searchCore = new PlayerSearchCore(cordova.getActivity());
        PlayNode playNode = ZcVideo.nodeList.get(channelNo + 1);

        deviceId = playNode.getDeviceId();
        playerclient.CameraSetPassword(deviceId, username, password, newPassword);
    }
}
